home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 April / EnigmA AMIGA RUN 17 (1997)(G.R. Edizioni)(IT)[!][issue 1997-04][EAR-CD].iso / EARCD / text / dtp / LabelMerge.lha / LabelMerge.rexx < prev   
OS/2 REXX Batch file  |  1996-11-26  |  45KB  |  1,049 lines

  1. /**************************************************************************/
  2. /*                                                                        */
  3. /*                         LabelMerge v1.0beta                            */
  4. /*                                                                        */
  5. /*                                                                        */
  6. /*                    Copyright ©1996 by Dick Whiting                     */
  7. /*                                                                        */
  8. /*========================================================================*/
  9. /*                                                                        */
  10. /*                                                                        */
  11. /* Report bugs, comments, etc. to:                                        */
  12. /*                                                                        */
  13. /*                   Dick Whiting <dwhiting@europa.com>                   */
  14. /*                                                                        */
  15. /*                          04 November 1996                              */
  16. /*                                                                        */
  17. /**************************************************************************/
  18.  
  19. OPTIONS RESULTS
  20.  
  21. /* Make sure rexx support is opened */
  22. IF ~SHOW('L','rexxsupport.library') THEN
  23.    CALL ADDLIB('rexxsupport.library',0,-30)
  24.  
  25. ADDRESS 'PAGESTREAM'
  26.  
  27.  
  28. /**************************************************************************/
  29. /*                                                                        */
  30. /*              You may change these variables if necessary               */
  31. /*                                                                        */
  32. /*========================================================================*/
  33. /*                                                                        */
  34. /* prefsfile is used to set the default intitial options, you CAN change  */
  35. /*           this to point to ANY valid path/filename you wish.           */
  36. /*           The path/filename MUST BE ENCLOSED IN QUOTES                 */
  37. /*                                                                        */
  38. /**************************************************************************/
  39.  
  40. prefsfile="PageStream3:scripts/TemplateData/LabelMerge.prefs"
  41.  
  42. /**************************************************************************/
  43. /*                                                                        */
  44. /* Main Logic:                                                            */
  45. /*                                                                        */
  46. /* 1) Setup Preferences - use internal defaults if no prefsfile           */
  47. /* 2) Get Data file, Template file, etc. using requester                  */
  48. /* 3) Calculate number of text blocks, pages, etc. needed                 */
  49. /* 4) Build each text block with the inserted values                      */
  50. /* 5) Return to user for visual inspection and printing                   */
  51. /*                                                                        */
  52. /* CANCELS and errors are handled by jumping to end of each routine if    */
  53. /* the doneselecting flag is set. Did it this way to avoid a zillion      */
  54. /* exit statements scattered throughout the code.                         */
  55. /*                                                                        */
  56. /**************************************************************************/
  57.  
  58. CALL Init
  59. CALL ReadPrefs
  60. CALL GetUserInfo
  61. CALL LoadPGS
  62. CALL OpenData
  63. CALL GetGuides
  64. CALL BldCoords
  65. do while doneselecting=0
  66.    CALL SelectModel
  67.    CALL BldBoxes
  68. end
  69.  
  70. exit 0
  71.  
  72. /**************************************************************************/
  73. /*                                                                        */
  74. /*  Show a nice:) requester for the user. Get the information needed.     */
  75. /*  The initial display includes any values set in the prefs file.        */
  76. /*                                                                        */
  77. /**************************************************************************/
  78. GetUserInfo:
  79.  
  80. allocarexxrequester '"Label Merge Setup"' 400 200
  81. handle.req=result
  82.  
  83. allocarexxlist
  84. delimlist=result     
  85. do i=1 to delimstem.0                       /* load delimiter char list   */
  86.    addarexxlist delimlist delimstem.i
  87. end
  88.  
  89. allocarexxlist
  90. vindlist=result
  91. do i=1 to vindstem.0                        /* load variable indicators   */
  92.    addarexxlist vindlist vindstem.i||'variable'||vindstem.i.1
  93. end
  94.  
  95. edge=10
  96. leftedge=145
  97. cyclen=145
  98. checklen=10
  99. getinfomsg='Select Options and Files - OK when done'   
  100. getinfo=1                                   /* control of requester loop  */
  101.  
  102. addarexxgadget handle.req EXIT 10 180 70 label "_OK"
  103. okhandle=result
  104.  
  105. addarexxgadget handle.req EXIT 320 180 70 label "_Cancel"
  106. cancelhandle=result
  107.  
  108. addarexxgadget handle.req CYCLE leftedge 10 cyclen label '"Field Delimiter:"' BORDER raised LIST delimlist CURRENT defaultdelim
  109. delimhandle=result
  110.  
  111. addarexxgadget handle.req CYCLE leftedge 25 cyclen label '"Variable Format:"' BORDER raised LIST vindlist CURRENT defaultvind
  112. varhandle=result
  113.  
  114. addarexxgadget handle.req CHECKBOX leftedge 40 checklen label '"Automatic Mode:"' labelpos LEFT BORDER raised CHECKED defaultmode
  115. modehandle=result
  116.  
  117. addarexxgadget handle.req CHECKBOX leftedge 55 checklen label '"Watch Me Work:"' labelpos LEFT BORDER raised CHECKED defaultwatchme
  118. refrhandle=result
  119.  
  120. addarexxgadget handle.req STRING edge+300 55 50 label '"Fuzziness"' labelpos LEFT BORDER raised STRING pctvar
  121. pcthandle=result
  122.  
  123. addarexxgadget handle.req STRING edge 95 350 label '"PAGESTREAM file:"' labelpos ABOVELEFT BORDER raised STRING templatefile
  124. temphandle=result
  125.  
  126. addarexxgadget handle.req EXIT edge+355 95 10 label "?"
  127. gettemphandle=result
  128.  
  129. addarexxgadget handle.req STRING edge 125 350 label '"ASCII data file:"' labelpos ABOVELEFT BORDER raised STRING datafile 
  130. datahandle=result
  131.  
  132. addarexxgadget handle.req EXIT edge+355 125 10 label "?"
  133. getdatahandle=result
  134.  
  135. addarexxgadget handle.req TEXT edge 155 380 label '"Label Merge Messages:"' labelpos ABOVELEFT BORDER text STRING '"'getinfomsg'"'
  136. infomsghandle=result
  137.  
  138. addarexxgadget handle.req EXIT 165 180 70 label "_Help"
  139. helphandle=result
  140.  
  141.  
  142. do while getinfo=1
  143.  
  144.    doarexxrequester handle.req
  145.    action=result
  146.  
  147.    getarexxgadget handle.req delimhandle current
  148.    delimchar=result
  149.  
  150.    getarexxgadget handle.req varhandle current
  151.    varchar=result
  152.  
  153.    getarexxgadget handle.req modehandle checked
  154.    modechar=result
  155.  
  156.    getarexxgadget handle.req refrhandle checked
  157.    refrchar=result
  158.  
  159.    getarexxgadget handle.req datahandle string
  160.    datachar=result
  161.    if datachar~=datafile then datafile=datachar
  162.  
  163.    getarexxgadget handle.req pcthandle string
  164.    pctchar=result
  165.  
  166.    getarexxgadget handle.req temphandle string
  167.    tempchar=result
  168.    if tempchar~=templatefile then templatefile=tempchar
  169.  
  170.    getinfomsg='Verify Options and Files - OK when ready'   
  171.    setarexxgadget handle.req infomsghandle STRING "'"getinfomsg"'"
  172.  
  173.    select
  174.      when action=okhandle then do            /* user is all done (maybe) */
  175.          i=varchar+1                        /* needs to base of 1 not 0   */
  176.          lvind=vindstem.i                   /* left variable indicator    */
  177.          rvind=vindstem.i.1                 /* right variable indicator   */
  178.          i=delimchar+1                      /* needs to base of 1 not 0   */
  179.          datadelim=delimstem.i.1            /* set data delimiter charact */
  180.          if modechar=1 then mode='AUTO' 
  181.                        else mode='MANUAL'
  182.          getinfo=0                          /* quit loop (maybe)          */
  183.          if datafile='' then do             /* no data file specified     */
  184.             getinfomsg='You must select an ASCII data file'
  185.             setarexxgadget handle.req infomsghandle STRING "'"getinfomsg"'"
  186.             getinfo=1                       /* continue loop              */
  187.          end
  188.          if templatefile='' then do         /* no PGS template specified  */
  189.             getinfomsg='You must select a PageStream template file'
  190.             setarexxgadget handle.req infomsghandle STRING "'"getinfomsg"'"
  191.             getinfo=1                       /* continue loop              */
  192.          end
  193.          if pctchar~='' & datatype(pctchar,'N'),
  194.             & pctchar <= .5 & pctchar >= 0 then pctvar=pctchar
  195.          else do
  196.             getinfomsg='Fuzziness must be between 0 and .5 inclusive'          
  197.             setarexxgadget handle.req pcthandle STRING pctvar
  198.             setarexxgadget handle.req infomsghandle STRING "'"getinfomsg"'"
  199.             getinfo=1                       /* continue loop              */
  200.          end         
  201.       end
  202.       when action=getdatahandle then do
  203.          getfile title "'Select the ASCII file'" PATH datapath LOAD POSBUTTON "Ok" NEGBUTTON "Cancel"
  204.          if rc=0 then do
  205.             datafile=result
  206.             setarexxgadget handle.req datahandle STRING "'"datafile"'" 
  207.          end
  208.       end
  209.       when action=gettemphandle then do
  210.          getfile title "'Select the PAGESTREAM file'" PATH templatepath LOAD POSBUTTON "Ok" NEGBUTTON "Cancel"
  211.          if rc=0 then do 
  212.             templatefile=result
  213.             setarexxgadget handle.req temphandle STRING "'"templatefile"'"
  214.          end
  215.       end
  216.       when action=cancelhandle then do
  217.          doneselecting=1                    /* user wants to quit         */
  218.          getinfo=0
  219.       end
  220.       otherwise do  /* should be the help button */
  221.          Call HelpDisplay
  222.       end
  223.    end        /* matches select */
  224. end  /* matches do getinfo */
  225.  
  226. freearexxrequester handle.req
  227. freearexxlist delimlist
  228. freearexxlist vindlist 
  229.  
  230. Return
  231.  
  232. /**************************************************************************/
  233. /* Get information about pagesize, margins, and guides                    */
  234. /* Locate ALL guides and store in arrays                                  */
  235. /* Build array describing all possible text block areas and mark the ones */
  236. /*    that are most likely actual label/form text areas.                  */
  237. /**************************************************************************/
  238. GetGuides:
  239.  
  240. if doneselecting=1 then signal GetGuidesExit /* skip all processing       */
  241.  
  242. 'getdimensions diminfo'                     /* get size of paper & orient.*/
  243.  
  244. orient=diminfo.orientation                  /* check orientation of page  */
  245.  
  246. if orient='PORTRAIT' then do
  247.    pgwidth=diminfo.width                    /* width of page              */
  248.    pgheight=diminfo.height                  /* height of page             */
  249. end
  250. else do                                     /* swap them                  */
  251.    pgwidth=diminfo.height                   /* width of page              */
  252.    pgheight=diminfo.width                   /* height of page             */
  253. end
  254.  
  255. 'getmarginguides marinfo'                   /* get margin guide info      */
  256. lmar=marinfo.inside                         /* left edge of first column  */
  257. rmar=marinfo.outside                        /* right edge of last column  */
  258. tmar=marinfo.top                            /* top margin                 */
  259. bmar=marinfo.bottom                         /* bottom margin              */
  260.  
  261. 'getcolumnguides cinfo'                     /* how many columns and gutter*/
  262. colcnt=cinfo.count                          /* number of cols             */
  263. cgut=cinfo.gutter                           /* size of gutter             */
  264.  
  265. 'getguides hinfo horizontal mpg right'      /* get horizontal guide info  */
  266. hcount=result                               /* number of horizontal guides*/
  267.  
  268. 'getguides vinfo vertical mpg right'        /* get vertical guide info    */
  269. vcount=result                               /* number of vertical guides  */
  270.  
  271. usewidth=pgwidth-(lmar+rmar)                /* useable width              */
  272. useheight=pgheight-(tmar+bmar)              /* useable height             */
  273.  
  274. colwidth=(usewidth-((colcnt-1)*cgut))/colcnt  /* width of a columns       */
  275.  
  276. /**************************************************************************/
  277. /*               Build arrays with all hguides and vguides                */
  278. /**************************************************************************/
  279. /*                         Handle the horizontals                         */
  280. /**************************************************************************/
  281.  
  282. hguide.0=0                                   /* init to NO horizontals    */
  283. joff=0                                       /* for pointer control       */
  284.  
  285. if tmar~=0 then do                           /* has a top margin          */
  286.    hguide.1=tmar                             /* store top margin          */
  287.    joff=1                                    /* bump pointer to next      */
  288. end
  289. do i=1 to hcount                             /* assume in order           */
  290.    j=joff+i                                  /* entry to load             */
  291.    k=i-1                                     /* hinfo starts with 0       */
  292.    hguide.j=hinfo.k                          /* load it                   */
  293. end
  294.  
  295. if bmar~=0 then do                           /* we have a bottom margin   */
  296.    j=joff+i                                  /* next entry slot           */
  297.    hguide.j=pgheight-bmar                    /* load it                   */
  298. end
  299.  
  300. hguide.0=j                                   /* save count of horizontals */
  301. hgidcnt=j                                    /* save count of horizontals */
  302.  
  303. /**************************************************************************/
  304. /*                    Handle vertical for columns first                   */
  305. /**************************************************************************/
  306.  
  307. vguide.0=0                                   /* init to NO verticals      */
  308. j=0                                          /* for pointer control       */
  309. voff=0                                       /* offset for first vertical */
  310.  
  311. if lmar~=0 then do                           /* has a left margin         */
  312.    vmargs.1=lmar                             /* store laft margin         */
  313.    voff=lmar                                 /* add in left margin size   */
  314.    j=1                                       /* bump pointer to next      */
  315. end
  316.  
  317. if colcnt~=0 then do                         /* we have column definitions*/
  318.    if cgut~=0 then do i=2 to (colcnt*2)      /* non zero gutters          */
  319.       if i//2=0 then vpos=((i/2)*colwidth)+(((i/2)-1)*cgut)+voff
  320.                 else vpos= ((i-1)/2)*(colwidth+cgut)+voff
  321.       if i/2=colcnt then do                  /* doing last vertical       */
  322.          if rmar~=0 then vpos=pgwidth-rmar   /* use right margin value    */
  323.       end
  324.       j=j+1                                  /* bump to next slot         */
  325.       vmargs.j=vpos                          /* store calculated values   */
  326.       vmargs.0=i                             /* running count of verts    */
  327.    end                                       /* end of ~0 gutter columns  */
  328.    else do
  329.       do i=1 to colcnt                       /* zero gutters between cols */
  330.          vpos=i*colwidth+voff                /* simple;)                  */
  331.          if i=colcnt then do                 /* doing last vertical       */
  332.             if rmar~=0 then vpos=pgwidth-rmar /* use right margin value   */
  333.          end
  334.          j=j+1                               /* bump to next slot         */
  335.          vmargs.j=vpos                       /* store the value           */
  336.       end                                    /* done with zero gutter cols*/
  337.    end                                       /* matches zero gutter else  */
  338. end                                          /* matches colcnt~=0         */
  339.  
  340. vmargs.0=j                                   /* save count for now        */
  341. vgidcnt=j                                    /* save count of verticals   */
  342.  
  343. /**************************************************************************/
  344. /*                 Now handle any vertical guides defined                 */
  345. /*                                                                        */
  346. /* Possible conditions:                                                   */
  347. /*    1) Columns only defined - copy array                                */
  348. /*    2) Vertical page guides only defined  - copy array as is            */
  349. /*       Vertical page guides with margins  - copy array with margins     */
  350. /*    3) Columns AND vertical page guides set - merge the two arrays      */
  351. /*    4) NO verticals set - return with error                             */
  352. /*                                                                        */
  353. /**************************************************************************/
  354.  
  355. j=0                                          /* pointer control           */
  356. select
  357.    when vcount=0 & vgidcnt~=0 then do i=0 to vgidcnt
  358.       vguide.i=vmargs.i
  359.       j=i
  360.    end
  361.    when vcount~=0 & vgidcnt=0 then do i=1 to vcount
  362.       j=j+1
  363.       if i=1 & lmar~=0 then do
  364.          vguide.1=lmar
  365.          j=j+1
  366.       end
  367.       k=i-1
  368.       vguide.j=vinfo.k
  369.       if i=vcount & rmar~=0 then do
  370.          j=j+1
  371.          vguide.j=pagewidth-rmar
  372.       end
  373.    end
  374.    when vcount~=0 & vgidcnt~=0 then do
  375.       Call MergeVerts
  376.    end
  377.    otherwise do
  378.       errmsg='This page has NO vertical guides or margins -- QUITTING'
  379.       Call ErrorDisplay
  380.       doneselecting=1                       /* skip selecting             */
  381.       signal GetGuidesExit                  /* exit from routine          */
  382.    end
  383. end
  384.  
  385. vguide.0=j                                  /* final count of entries     */
  386. vgidcnt=j                                   /* save count of verticals    */
  387.  
  388. GetGuidesExit:
  389.  
  390. Return
  391.  
  392. /**************************************************************************/
  393. /*                   Merge the two vertical info arrays                   */
  394. /**************************************************************************/
  395. MergeVerts:
  396.  
  397. j=1                                         /* ptr for vguide array       */
  398. i=1                                         /* ptr for vmargs array       */
  399. k=0                                         /* ptr for vinfo array        */
  400. kdone=0                                     /* flag for when done         */
  401. idone=0                                     /* flag for when done         */
  402. do loop=1                                   /* loop until leave           */
  403.    select
  404.       when kdone=1 & idone=1 then leave loop  /* all merged - I hope:)    */
  405.       when kdone=1 & idone=0 then do
  406.          vguide.j=vmargs.i
  407.          j=j+1
  408.          i=i+1
  409.          if i>vgidcnt then idone=1
  410.       end
  411.       when kdone=0 & idone=1 then do
  412.          vguide.j=vinfo.k
  413.          j=j+1
  414.          k=k+1
  415.          if k=vcount then kdone=1
  416.       end
  417.       when vmargs.i > vinfo.k then do
  418.          vguide.j=vinfo.k
  419.          j=j+1
  420.          k=k+1
  421.          if k=vcount then kdone=1
  422.       end
  423.       when vinfo.k > vmargs.i then do
  424.          vguide.j=vmargs.i
  425.          j=j+1
  426.          i=i+1
  427.          if i>vgidcnt then idone=1
  428.       end
  429.       otherwise do        /* must be equal - use 1 and bump all pointers */
  430.          vguide.j=vmargs.i
  431.          j=j+1
  432.          i=i+1
  433.          k=k+1
  434.          if i>vgidcnt then idone=1
  435.          if k=vcount then kdone=1
  436.       end
  437.    end
  438. end
  439.  
  440. j=j-1                                       /* remove last increment      */
  441.  
  442. Return
  443.  
  444. /**************************************************************************/
  445. /*         Use guide arrays to build coords of each possible box          */
  446. /*          Mark which ones are true boxes and which are spacers          */
  447. /**************************************************************************/
  448. BldCoords:
  449.  
  450. if doneselecting=1 then signal BldCoordsExit /* skip all processing       */
  451.  
  452. hboxcnt=(vguide.0)-1                        /* number of boxes across     */
  453. vboxcnt=(hguide.0)-1                        /* number of boxes down       */
  454. bguide=hguide.hgidcnt                       /* bottom guide               */
  455. rguide=vguide.vgidcnt                       /* right guide                */
  456.  
  457. /**************************************************************************/
  458. /*       Load array with upper left coords for each box       (ulx,uly)   */
  459. /*       Load array with lower right coord for each box       (lrx,lry)   */
  460. /*       Load array with width and height  for each box       (w,h)       */
  461. /*       Flag each box as being a valid text size block or not (Y/N)      */
  462. /*                                                                        */
  463. /* Format of array: boxdesc.ulx.uly.lrx.lry.widht.height.flag             */
  464. /*                                                                        */
  465. /**************************************************************************/
  466.  
  467. do i=1 to hboxcnt
  468.    do j=1 to vboxcnt
  469.       k=((i-1)*vboxcnt)+j                   /* box being handled          */
  470.       nexth=i+1                             /* next horizontal guide      */
  471.       nextv=j+1                             /* next vertical guide        */
  472.       boxdesc.k=vguide.i                    /* xcoord of top/left corner  */
  473.       boxdesc.k.1=hguide.j                  /* ycoord of top/left corner  */
  474.       if i=hboxcnt then boxdesc.k.1.1=rguide  /* lower right xcoord       */
  475.                    else boxdesc.k.1.1=vguide.nexth
  476.       if j=vboxcnt then boxdesc.k.1.1.1=bguide  /* lower right ycoord     */
  477.                    else boxdesc.k.1.1.1=hguide.nextv
  478.       boxdesc.k.1.1.1.1=boxdesc.k.1.1 - boxdesc.k /* width of box         */
  479.       boxdesc.k.1.1.1.1.1=boxdesc.k.1.1.1 - boxdesc.k.1 /* height of box  */
  480.    end
  481. end
  482.  
  483. boxdesc.0=hboxcnt*vboxcnt                   /* number of possible boxes   */
  484.  
  485. BldCoordsExit:
  486.  
  487. Return
  488.  
  489. /**************************************************************************/
  490. /*                  this is where the boxes are selected                  */
  491. /**************************************************************************/
  492. SelectModel:
  493.  
  494. if doneselecting=1 then signal SelectModelExit
  495.  
  496. if refrchar=0 then do                       /* turn off display updates   */
  497.    'refresh wait'
  498. end
  499.  
  500. if mode='AUTO' then do
  501.    targwidth=boxdesc.1.1.1.1.1              /* width of model box         */
  502.    targheight=boxdesc.1.1.1.1.1.1           /* height of model box        */
  503.    ulx=boxdesc.1                            /* upper left x-coord         */
  504.    uly=boxdesc.1.1                          /* upper left y-coord         */
  505.    midx=ulx+targwidth/2                     /* xcoord middle of object    */ 
  506.    midy=uly+targheight/2                    /* ycoord middle of object    */ 
  507.    'selectobject at ' midx midy             /* select object for id       */
  508. end
  509. else do
  510.    'settoolmode object'                     /* turn on object tool        */
  511.    'getcoord click message "Click in model text frame"'
  512.  
  513.    if rc~=0 then do                         /* user canceled requester    */
  514.       doneselecting=1                       /* set flag                   */
  515.       signal SelectModelExit                /* need to quit               */
  516.    end
  517.  
  518.    'selectobject at ' click.x click.y
  519.  
  520.    'getobject type otype boundingbox selobj'
  521.  
  522.    if ~datatype(otype,'N') then do
  523.       errmsg='You did not select a TEXT FRAME -- QUITTING'
  524.       Call ErrorDisplay
  525.       doneselecting=1                       /* set flag                   */
  526.       signal SelectModelExit                /* need to quit               */
  527.    end
  528.  
  529.    ulx=selobj.left
  530.    uly=selobj.top
  531.    targwidth=selobj.right - selobj.left
  532.    targheight=selobj.bottom - selobj.top
  533. end
  534.  
  535. 'getobject type otype'                      /* get id of this text block  */
  536. objid=result                                /* id is returned in result   */
  537.  
  538. if otype~=11 then do
  539.    errmsg='This is not a text frame -- QUITTING'
  540.    Call ErrorDisplay
  541.    doneselecting=1                          /* set flag                   */
  542.    signal SelectModelExit                   /* need to quit               */
  543. end
  544.  
  545. 'selectobject none'                         /* have to free object        */
  546.  
  547. midx=ulx+targwidth/2                        /* xcoord middle of object    */ 
  548. midy=uly+targheight/2                       /* ycoord middle of object    */ 
  549.  
  550. 'settoolmode text'                          /* change to text mode        */
  551. 'selecttext at 'midx midy                   /* select text in first box   */
  552. 'selecttext at 'midx midy ' all'            /* select text in first box   */
  553. 'getarticlewordcount'                       /* get number of words        */
  554. wordcount=result
  555.  
  556. if wordcount=0 then do
  557.    errmsg='NO text in this block -- QUITTING'
  558.    Call ErrorDisplay
  559.    doneselecting=1                          /* set flag                   */
  560.    signal SelectModelExit                   /* need to quit               */
  561. end
  562.  
  563. 'exporttext file 'importfile 'filter ascii amiga textcode pagestream force'
  564. 'cuttext'                                   /* delete the text            */
  565. 'settoolmode object'                        /* change to object mode      */
  566. 'deleteobject objectid' objid               /* delete the text frame obj  */
  567.  
  568. matchboxes=0                                /* boxes matching model       */
  569.  
  570. do i=1 to boxdesc.0
  571.    testwidth=boxdesc.i.1.1.1.1              /* width of box being tested  */
  572.    testheight=boxdesc.i.1.1.1.1.1           /* height of box being tested */
  573.    widthvar=abs(targwidth-testwidth)/targwidth /* variance in width       */
  574.    heightvar=abs(targheight-testheight)/targheight  /* variance in height */
  575.    if widthvar<=pctvar & heightvar<=pctvar then do
  576.                       boxdesc.i.1.1.1.1.1.1='Y'
  577.                       matchboxes=matchboxes+1 /* one more found           */
  578.                    end
  579.                    else boxdesc.i.1.1.1.1.1.1='N'
  580. end
  581.  
  582. if matchboxes=0 then do                     /* no matches found          */
  583.    errmsg='NO text blocks match Model - QUITTING'
  584.    Call ErrorDisplay
  585.    doneselecting=1                          /* set flag                  */
  586.    signal SelectModelExit                   /* need to quit              */
  587. end
  588.  
  589. SelectModelExit:
  590.  
  591. Return
  592.  
  593. /**************************************************************************/
  594. /*                                                                        */
  595. /* Build all boxes and fill with modified text                            */
  596. /*                                                                        */
  597. /**************************************************************************/
  598. BldBoxes:
  599.  
  600. if doneselecting=1 then signal BldBoxesExit
  601.  
  602. validboxes=0
  603. impstring.=' '
  604. impcnt=0
  605.  
  606. goodopen=open('IMPX',importfile,'R')
  607. if ~goodopen then do
  608.    errmsg='Could not open 'importfile' for input -- QUITTING'
  609.    Call ErrorDisplay
  610.    doneselecting=1                          /* set flag                   */
  611.    signal BldBoxesExit
  612. end   
  613.  
  614. do until eof('IMPX')                        /* read until end of file     */
  615.    impcnt=impcnt+1                          /* next import/export record  */
  616.    impstring.impcnt=readln('IMPX')          /* read next record           */
  617. end                                         /* matches until EOF          */
  618.  
  619. result=close('IMPX')                        /* close the import file      */
  620.  
  621. /**************************************************************************/
  622. /*          This is where we need to control the number of pages          */
  623. /**************************************************************************/
  624.  
  625. pagecnt=datacnt%matchboxes                  /* how many whole pages       */
  626. pagepart=datacnt//matchboxes                /* partial pages              */
  627. if pagepart~=0 then pagecnt=pagecnt+1       /* handle extra records       */
  628. dataptr=0                                   /* initialize data pointer    */
  629.  
  630. openbusyrequester message 'Processing...' thermometer abort enabled total datacnt current 0
  631. bh=result                                   /* pointer to requester       */
  632. bhopen=1                                    /* set a flag for later       */
  633.  
  634. do pagenum=1 to pagecnt                     /* end of loop is within code */
  635.    do i=1 to boxdesc.0                      /* loop thru box definitions  */
  636.       if boxdesc.i.1.1.1.1.1.1='Y' then do  /* need to draw this one      */
  637.          ulx=boxdesc.i
  638.          uly=boxdesc.i.1
  639.          lrx=boxdesc.i.1.1
  640.          lry=boxdesc.i.1.1.1
  641.          'drawcolumn ' ulx uly lrx lry column 1
  642.          validboxes=validboxes+1
  643.          'selecttext at ' ulx uly
  644.          dataptr=dataptr+1
  645.          Call ChangeText
  646.          if doneselecting=1 then signal BldBoxesExit /* something went wrong */
  647.          'inserttext file ' importfile 'filter ascii amiga textcode pagestream'
  648.          getbusyrequester bh                /* test for abort             */
  649.          if result=1 then do
  650.                           doneselecting=1     /* indicate time to quit    */
  651.                           signal BldBoxesExit
  652.                      end
  653.                      else setbusyrequester bh current dataptr
  654.          if dataptr=datacnt then leave pagenum /* all data recs processed */
  655.          if validboxes=matchboxes then do   /* is it end of a full page ? */
  656.             i=999999                        /* force end of boxdesc loop  */
  657.             validboxes=0                    /* reset boxes drawn on page  */
  658.             'Display page next'             /* go to next page            */
  659.          end                                /* matches end of page        */
  660.       end                                   /* matches boxdesc='Y'        */
  661.    end                                      /* matches do i=1 to boxdesc.0*/
  662. end
  663.  
  664. 'Display page 1'                            /* go to page 1               */
  665.  
  666. if mode='AUTO' then do                      /* check mode again           */   
  667.    doneselecting=1                          /* only do once               */
  668. end
  669.  
  670. if refrchar=0 then do                       /* refresh page 1 display     */
  671.    'refresh continue'
  672. end
  673.  
  674. BldBoxesExit:
  675.  
  676. if bhopen=1 then do                         /* busy req is open           */
  677.    closebusyrequester bh                    /* close it                   */
  678.    bhopen=0                                 /* show we closed it          */
  679. end
  680.  
  681. Return
  682.  
  683. /**************************************************************************/
  684. /*                                                                        */
  685. /*         Change copy of exported text, rewrite export file              */
  686. /*        !!! Don't use variable 'i' within this routine !!!              */
  687. /**************************************************************************/
  688. ChangeText:
  689.  
  690. do j=1 to impcnt
  691.    impcopy.j=impstring.j
  692. end
  693.  
  694. /**************************************************************************/
  695. /*                     Here is the actual change code                     */
  696. /*                     (what a lot of work to get here;))                 */
  697. /**************************************************************************/
  698.  
  699. do j=1 to impcnt                            /* loop thru copy of text     */
  700.    do varptr=1 to varcnt
  701.       repvar=varname.varptr                 /* search string              */
  702.       replen=length(repvar)                 /* replacement length         */
  703.       do varloop=1
  704.          varpos=pos(repvar,impcopy.j)       /* look for variable to rep.  */
  705.          if varpos~=0 then do
  706.             repstr1=substr(impcopy.j,1,varpos-1) /* part before variable  */
  707.             repstr2=substr(impcopy.j,varpos+replen) /* part after it      */
  708.             impcopy.j=repstr1||datavar.dataptr.varptr||repstr2
  709.          end
  710.          else leave varloop
  711.       end
  712.    end
  713. end
  714.  
  715. goodopen=open('IMPX',importfile,'W')
  716. if ~goodopen then do
  717.    errmsg='Could not open 'importfile' for output -- QUITTING'
  718.    Call ErrorDisplay
  719.    doneselecting=1                          /* set flags                  */
  720.    Signal ChangeTextExit
  721. end
  722.  
  723. do j=1 to impcnt                            /* write array back to file   */
  724.    foo=writeln('IMPX',impcopy.j)            /* write next record          */
  725. end
  726.  
  727. result=close('IMPX')                        /* close the export file      */
  728.  
  729. ChangeTextExit:
  730.  
  731. Return
  732.  
  733. /**************************************************************************/
  734. /*                                                                        */
  735. /*            Read in the information from the .prefs file                */
  736. /*                                                                        */
  737. /**************************************************************************/
  738. ReadPrefs:
  739.    goodopen=open('Prefs',prefsfile,'R')
  740.    if ~goodopen then do
  741.       errmsg='Could not open Prefs file -- using Defaults'
  742.       Call ErrorDisplay
  743.    end
  744.    else do
  745.       do until eof('Prefs')
  746.          pref=readln('Prefs')
  747.          if pref~=' ' & pref~='#' & pref~='' then do
  748.             if pos('#',pref)~=1 then do
  749.                if pos('#',pref)>2 then do
  750.                   pref=substr(pref,1,pos('#',pref)-1)
  751.                end
  752.                pref=strip(pref)
  753.                interpret pref
  754.             end
  755.          end
  756.       end
  757.    end
  758.    result=close('Prefs')
  759.  
  760. Return
  761.  
  762. /**************************************************************************/
  763. /*                                                                        */
  764. /*                     Load PageStream file                               */
  765. /*                                                                        */
  766. /**************************************************************************/
  767. LoadPGS: 
  768.  
  769. if doneselecting=1 then signal LoadPGSExit  /* error or cancel            */
  770.  
  771. 'open ' "'"templatefile"'"
  772. if rc~=0 then do
  773.    errmsg='Unable to open PageStream file: 'le||le||templatefile
  774.    CALL ErrorDisplay
  775.    doneselecting=1
  776. end
  777.  
  778. LoadPGSExit:
  779.  
  780. Return
  781.  
  782. /**************************************************************************/
  783. /*                                                                        */
  784. /*                     Read the Data file into array                      */
  785. /*                                                                        */
  786. /**************************************************************************/
  787. OpenData:
  788.  
  789. if doneselecting=1 then signal OpenDataExit /* error or cancel            */
  790.  
  791.    varcnt=1                                 /* assume we'll have a header */
  792.    goodopen=open('Data',datafile,'R')
  793.    if ~goodopen then do
  794.       errmsg='Could not open data file: 'le||le||datafile
  795.       Call ErrorDisplay
  796.       doneselecting=1
  797.       signal OpenDataExit
  798.    end
  799.  
  800.    if lvind='<' then do                     /* handle PGS escape coding   */
  801.       lvind='<\<>'
  802.       rvind='<\>>'
  803.    end
  804.  
  805. ReadHeader:
  806.  
  807.    headln=readln('Data')
  808.    delimpos=pos(datadelim,headln)           /* find first delimiter       */
  809.    do while delimpos~=0                     /* loop across header record  */
  810.       rawvar=substr(headln,1,delimpos-1)    /* variable name              */
  811.       rawvar=strip(rawvar)                  /* strip blanks               */
  812.       varname.varcnt=lvind||rawvar||rvind   /* concat with indicators     */
  813.       headln=substr(headln,delimpos+1)      /* shorten remainin data rec  */
  814.       delimpos=pos(datadelim,headln)        /* find next delimiter        */
  815.       varcnt=varcnt+1                       /* increment counter          */
  816.    end
  817.    rawvar=headln                            /* last variable name         */
  818.    rawvar=strip(rawvar)                     /* strip blanks               */
  819.    varname.varcnt=lvind||rawvar||rvind      /* concat with indicators     */
  820.    varname.0=varcnt                         /* store variable count       */
  821.  
  822.    if varcnt=1 & (headln='' | headln=' ') then do  /* no header info      */
  823.       errmsg='NO header found in data file -- QUITTING'
  824.       Call ErrorDisplay
  825.       doneselecting=1
  826.       signal OpenDataExit
  827.    end
  828.  
  829. ReadData:
  830.  
  831.    do until eof('Data')                     /* read until end of file     */
  832.       dataln=readln('Data')                 /* read next record           */
  833.       if dataln~='' then do                 /* skip null records          */
  834.          datacnt=datacnt+1                  /* record count being done    */
  835.          do i=1 to varcnt                   /* parse values from data rec */
  836.             delimpos=pos(datadelim,dataln)  /* location of delimiter char */
  837.             if delimpos~=0 then do          /* found a delimiter          */
  838.                datavar.datacnt.i=substr(dataln,1,delimpos-1)
  839.                dataln=substr(dataln,delimpos+1) /* shorten data record    */
  840.             end
  841.             else do
  842.                datavar.datacnt.i=dataln     /* use remainder of record    */
  843.             end
  844.          end                                /* matches i=1 to varcnt      */
  845.       end                                   /* matches non null record    */
  846.    end                                      /* matches until EOF          */
  847.  
  848.    datavar.0=datacnt                        /* store count of records     */
  849.    result=close('Data')                     /* close the data file        */
  850.  
  851. OpenDataExit:
  852.  
  853. Return
  854.  
  855. /**************************************************************************/
  856. /*                                                                        */
  857. /*                     Setup variables, lists, etc.                       */
  858. /*                                                                        */
  859. /**************************************************************************/
  860. Init:
  861.  
  862. le=d2c(10)                             /* line end text displaying        */
  863.  
  864. delimstem.0=3                          /* change this if add delimieters  */
  865. delimstem.1='Comma'                    /* name of character               */
  866. delimstem.1.1=','                      /* character itself                */
  867. delimstem.2='Tab' 
  868. delimstem.2.1=d2c(09)
  869. delimstem.3='SemiColon'
  870. delimstem.3.1=';'
  871.  
  872. defaultdelim=0                         /* default data delimiter          */
  873.  
  874. vindstem.0=4     /* number of pairs -- change this if add var indicators  */
  875. vindstem.1='<'                         /* left indicator of pair          */
  876. vindstem.1.1='>'                       /* right indicator of pair         */
  877. vindstem.2='«'                         /* left indicator of pair          */
  878. vindstem.2.1='»'                       /* right indicator of pair         */
  879. vindstem.3='['                         /* left indicator of pair          */
  880. vindstem.3.1=']'                       /* right indicator of pair         */
  881. vindstem.4='{'                         /* left indicator of pair          */
  882. vindstem.4.1='}'                       /* right indicator of pair         */
  883.  
  884. defaultvind=0                          /* default variable indicator      */
  885.  
  886. varname.=' '                           /* initialize var names to blank   */
  887. varname.0=0                            /* initialize variable count to 0  */
  888. varcnt=0                               /* initialize to NO variable names */
  889.  
  890. datavar.=' '                           /* initialize var fields to blanks */
  891. datavar.0=0                            /* initialize record count to zero */
  892. datacnt=0                              /* initialize to NO data records   */
  893.  
  894. pctvar=.10                             /* allow 10% variance in box sizes */
  895.  
  896. mode='AUTO'                            /* default to automatic handling   */
  897. defaultmode="True"                     /* Automatic mode of processing    */
  898.  
  899. defaultwatchme="True"                  /* default to screen refreshing    */
  900.  
  901. datapath='PageStream3:'                /* use PGS3 path for requesters    */
  902. datafile=''                            /* init to missing                 */
  903. templatepath='PageStream3:'            /* use PGS3 path for requesters    */
  904. templatefile=''                        /* init to missing                 */
  905. importfile="T:LabelMerge.import"       /* name of temporary file          */
  906.  
  907. doneselecting=0                        /* haven't finished selections yet */
  908. bhopen=0                               /* no busy requester yet           */
  909.  
  910. errmsg=''                              /* no errors to start with         */
  911.  
  912. /**************************************************************************/
  913. /*        Internal Help Information for Label Merge Program               */
  914. /*                                                                        */
  915. /*        each group can be no longer than 255 characters                 */
  916. /*        this is roughly 6 complete lines of help text                   */
  917. /**************************************************************************/
  918.  
  919. helppages=9                            /* number of pages of help info    */
  920.  
  921.  helpmsg.1='See LabelMerge.readme for complete details'le||le||,
  922. 'Prior to using this script you must create',
  923. 'a PAGESTREAM TEMPLATE file that describes',
  924. 'the label sheet you are going to print.'le||le||,
  925. 'Each print area must be bounded by guides',
  926. 'and have a model text frame defined.'   
  927.  
  928.  helpmsg.2='The text allows variables using any of',
  929. 'these pairs: < >, « », [ ], or { }'le||le||,
  930. 'The « » pair can be produced using',
  931. 'Alt-9 and Alt-0 keys.'le||le'The default indicators',
  932. 'are < >.'le||le'Example: <name> <addr> etc.'le||le||,
  933. 'Only one type is allowed within a single template.'
  934.  
  935.  helpmsg.3='The DATA FILE requires a header with the',
  936. 'variable names separated by the delimiter set in the',
  937. 'FIELD DELIMITER gadget'le||le||,
  938. 'The remaining records contain the data that will replace',
  939. 'the variables in the template'le||le||,
  940. 'Each data field must be separated by the DELIMITER.'
  941.  
  942.  helpmsg.4='The built in options for DELIMITER are:'le||le||,
  943. 'COMMA'le||le||,
  944. 'TAB'le||le||,
  945. 'SEMI-COLON'le||le||,
  946. 'The default is COMMA'
  947.  
  948.  helpmsg.5='The AUTO option expects only ONE text',
  949. 'frame type in the template and that the model is the',
  950. 'TOP LEFT text frame.'le||le||,
  951. 'Turning AUTO OFF allows for multiple sizes of text frames',
  952. 'and for a template that does not match the expected',
  953. 'default.'
  954.  
  955.  helpmsg.6='The WATCH-ME-WORK option shows you all',
  956. 'of the processing as it takes place.'le||le||,
  957. 'Turning it off limits the number of screen refreshes.'le||le||,
  958. 'On my A4000/040 this is about 14% faster.'
  959.  
  960.  helpmsg.7='The FUZZINESS value controls how close',
  961. 'a bounded area must be to the model to be considered as a match.'le||le||,
  962. 'A target must be within this variance in',
  963. 'width and height.'le||le||'The default is .10'                  
  964.  
  965.  helpmsg.8='IN CASE OF EMERGENCY:'le||le||,
  966. 'If you must STOP LabelMerge in the midst of processing'le||le||,
  967. '1) Switch to WorkBench'le||le||,
  968. '2) Open a CLI window'le||le||,
  969. '3) Enter <HI> (without the brackets) and it should quit shortly'
  970.  
  971.  helpmsg.9='For BUG reports, comments, etc.'le||le||,
  972. 'Contact:'le||le||,
  973. 'Dick Whiting'le||le||,
  974. 'email: dwhiting@europa.com'le||le||,
  975. 'If you use and LIKE this effort, my kids would REALLY love a',    
  976. 'postcard from where ever you live'le||le||,
  977. '28590 S. Beavercreek Rd.'le||,
  978. 'Mulino, Oregon 97042'le||,
  979. 'USA'
  980.  
  981. Return
  982.  
  983. /**************************************************************************/
  984. /*                                                                        */
  985. /*                           Display HELP information                     */
  986. /*                                                                        */
  987. /**************************************************************************/
  988. HelpDisplay:
  989.  
  990. allocarexxrequester '"Label Merge Help Information"' 400 200
  991. handle.helpreq=result
  992.  
  993. addarexxgadget handle.helpreq MULTILINE 10 10 380 160 BORDER none STRING ' '
  994. helpmsghandle=result
  995.  
  996. addarexxgadget handle.helpreq EXIT 10 180 70 label "_More"
  997. morehandle=result
  998.  
  999. addarexxgadget handle.helpreq EXIT 320 180 70 label "_Cancel"
  1000. hcancelhandle=result
  1001.  
  1002. do hshow=1 to helppages
  1003.  
  1004.    setarexxgadget handle.helpreq helpmsghandle STRING '"'helpmsg.hshow'"'
  1005.    
  1006.    if hshow=helppages then do
  1007.       setarexxgadget handle.helpreq morehandle label "_Again"
  1008.    end
  1009.    else do
  1010.       setarexxgadget handle.helpreq morehandle label "_More"
  1011.    end
  1012.  
  1013.    doarexxrequester handle.helpreq
  1014.    haction=result
  1015.  
  1016.    if haction=hcancelhandle then leave hshow
  1017.    if hshow=helppages & haction=morehandle then hshow=0 
  1018.  
  1019. end
  1020.  
  1021. freearexxrequester handle.helpreq
  1022.  
  1023. Return
  1024. /**************************************************************************/
  1025. /*                                                                        */
  1026. /*                          Display ERROR information                     */
  1027. /*                                                                        */
  1028. /**************************************************************************/
  1029. ErrorDisplay:
  1030.  
  1031. errmsg=errmsg||le||le||'See LabelMerge.readme for usage details'            
  1032.  
  1033. allocarexxrequester '"Label Merge ERROR Information"' 400 200
  1034. handle.errreq=result
  1035.  
  1036. addarexxgadget handle.errreq MULTILINE 10 10 380 160 BORDER none STRING '"'errmsg'"'
  1037. errmsghandle=result
  1038.  
  1039. addarexxgadget handle.errreq EXIT 165 180 70 label "_Done"
  1040. donehandle=result
  1041.  
  1042. doarexxrequester handle.errreq
  1043. haction=result
  1044.  
  1045. freearexxrequester handle.errreq
  1046.  
  1047. Return
  1048.  
  1049.